﻿using Common;
using IService;
using Microsoft.Data.SqlClient.Server;
using Model.Models;
using ModelDto;
using SqlserverManager;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace Service
{
    [Service]
    public class CodeCreateTableService: ICodeCreateTableService
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;

        public CodeCreateTableService(IDbConnectionFactory dbConnectionFactory)
        {
            _dbConnectionFactory = dbConnectionFactory;
        }


        /// <summary>
        /// 获取列表数据
        /// </summary>
        /// <param name="keywords">关键字</param>
        /// <returns></returns>
        public async Task<List<CodeCreateTable>> GetList(string keywords)
        {
            var Context = _dbConnectionFactory.CreateDbContext();

            var list = await Context.Queryable<CodeCreateTable>()
                .WhereIF(!string.IsNullOrWhiteSpace(keywords),a=> a.Name.Contains(keywords) || a.Remark.Contains(keywords))
                .ToListAsync();

       
            return list;

        }

        /// <summary>
        /// 生成代码
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        public CodeCreateTableResponse CodeCreate(string tableName)
        {
            CodeCreateTableResponse response = new CodeCreateTableResponse();

            //使用一下 Model.dll 方便反射
            Account s = new Account();


            //实体类的命名空间 约定死
            string nspace = "Model.Models";

            var list = AppDomain.CurrentDomain.GetAssemblies();


            //Assembly asm = list.FirstOrDefault(x => x.FullName.Contains("Model"));
            Assembly asm = list.FirstOrDefault(x => x.ManifestModule.Name.ToLower() == "Model.dll".ToLower());
 
            var types = asm.GetTypes();

            if (types != null && types.Length > 0)
            {

                var type = types.Where(a => a.IsClass && a.Namespace == nspace && a.Name.ToLower()== tableName.ToLower()).FirstOrDefault();

                if (type==null)
                {
                    return response;
                }

                PropertyInfo[] properties = type.GetProperties();

                //当前表字段集合
                List<CodeCreateTableColInfo> colList = new List<CodeCreateTableColInfo>();

                List<string> filterlist = new List<string>() {
                    "DeleteTime".ToLower(),
                    "CreateUser".ToLower(),
                    "UpdateUser".ToLower(),
                    "DeleteUser".ToLower(),
                    "IsDelete".ToLower(),
                    "Extend1".ToLower(),
                    "Extend2".ToLower(),
                    "Extend3".ToLower(),
                    "remark".ToLower(),
                    "id".ToLower(),
                };

                foreach (PropertyInfo propertyInfo in properties)
                {
                    string name = propertyInfo.Name;
                    var typenameCurrent = propertyInfo.PropertyType.Name;

                    if (filterlist.Contains(name.ToLower()) == false)
                    {
                        string tempStr = name.Substring(0, 1).ToLower() + name.Substring(1);

                        string typeName = TypeStr(typenameCurrent);

                        string discriptionStr = "";
                        object[] obj = propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), true);
                        foreach (DescriptionAttribute desc in obj)
                        {
                            discriptionStr = desc.Description;
                        }

                        if (string.IsNullOrWhiteSpace(discriptionStr)){
                            discriptionStr = tempStr;
                        }

                        colList.Add(new CodeCreateTableColInfo()
                        {
                            Name = tempStr,
                            NameY = name,
                            Remark = discriptionStr,
                            TypeName = typeName
                        });
                    }


                   

                }

                tableName = tableName.Replace("_", "");

                response.Code1 = GetCode1(colList, tableName);
                response.Code2 = GetCode2(colList, tableName);
                response.Code3 = GetCode3(colList, tableName);


            }



            return response;
        }


        /// <summary>
        /// 后端接口代码生成
        /// </summary>
        /// <param name="colList"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private string GetCode3(List<CodeCreateTableColInfo> colList,string tableName)
        {
            string tableName2 = tableName.Substring(0, 1).ToLower() + tableName.Substring(1);

            string str = "";

            foreach (var item in colList)
            {
                if (item.NameY.ToLower()!= "CreateTime".ToLower() && item.NameY.ToLower() != "UpdateTime".ToLower())
                {
                    str += string.Format(@"entity.{0} = request.{0};", item.NameY);
                }


            }

            string res = string.Format(@"using Api.Filter;
using IService;
using Microsoft.AspNetCore.Mvc;
using ModelDto;
using Newtonsoft.Json;
using System.Collections.Generic;
using System;
using System.Linq;
using Model.Models;
using Common;

namespace Api.Controllers
{{
    /// <summary>
    /// {0}接口
    /// </summary>
    [Route(""api/[controller]/[action]"")]
    [ApiController]
    [ServiceFilter(typeof(MyTokenFilterAttribute))]
    public class {0}Controller : ControllerBase
    {{
        private readonly I{0}Service _{1}Service;
        private readonly IEntityMapperHelper _entityMapperHelper;

        public {0}Controller(I{0}Service {1}Service, IEntityMapperHelper entityMapperHelper)
        {{
            _{1}Service = {1}Service;
            _entityMapperHelper = entityMapperHelper;
        }}

   


        /// <summary>
        /// 获取{0}列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public JsonResultL Get{0}List({0}RequestPage request)
        {{
            JsonResultL response = new JsonResultL();

            string tempUser = HttpContext.Request.Headers[""LUserInfo""].ToString();
            AccountLoginInfo CurrentUser = JsonConvert.DeserializeObject<AccountLoginInfo>(tempUser);

            if (CurrentUser == null || CurrentUser.Account == null)
            {{
                return response.TokenFail(""用户异常"");
            }}

            List<{0}Response> list = new List<{0}Response>();


            //数据少的读缓存一次性取出后再分页 数据大的去数据库分页取数据
            List<{0}> resList = null;
            #region 读redis缓存

            resList = _{1}Service.GetListCache();

            //关键字条件筛选
            //if (!string.IsNullOrWhiteSpace(request.KeyWords))
            //{{
            //    resList = resList.Where(a => a.Col1.Contains(request.KeyWords)).ToList();
            //}}

            int count = resList.Count();
            if (request.PageIndex <= 1)
            {{
                request.PageIndex = 1;
            }}
            if (request.PageSize < 1)
            {{
                request.PageSize = 10;
            }}

            resList = resList.OrderBy(a => a.CreateTime).Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize).ToList();

            #endregion

            #region 读数据库

            //resList = _{1}Service.QueryList(a => true, request.PageIndex, request.PageSize, out count, b => b.CreateTime, true);

            #endregion

            if (resList != null && resList.Count > 0)
            {{
                foreach (var item in resList)
                {{
                    var temp = _entityMapperHelper.Mapper<{0}Response, {0}>(item);

                    list.Add(temp);
                }}
            }}
            return response.Sucess(new {{ list = list, total = count }});
        }}

        /// <summary>
        /// {0} - 新增 修改
        /// </summary>
        /// <param name=""request""></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResultL Save{0}({0}Request request)
        {{
            JsonResultL response = new JsonResultL();
            DateTime now = DateTime.Now;
            string tempUser = HttpContext.Request.Headers[""LUserInfo""].ToString();
            AccountLoginInfo CurrentUser = JsonConvert.DeserializeObject<AccountLoginInfo>(tempUser);

            if (CurrentUser == null || CurrentUser.Account == null)
            {{
                return response.TokenFail(""用户异常"");
            }}

            var entity = new {0}();

            if (string.IsNullOrWhiteSpace(request.Id))
            {{
                //新增

                //过滤条件
                //var entity = _{1}Service.Query(a => a.Name == request.Name);
                //if (entity != null)
                //{{
                //    return response.Fail(""名称已存在"");
                //}}


                
                entity.Remark = request.Remark;
                entity.CreateTime = now;
                entity.CreateUser = CurrentUser.Account.Id;

                {2}


                bool flag = _{1}Service.Add(entity);

                return flag ? response.Sucess(""新增成功"") : response.Fail(""新增失败"");
            }}
            else
            {{
                //修改

                //过滤条件
                //entity = _{1}Service.Query(a => a.Name == request.Name && a.Id != request.Id);
                //if (entity != null)
                //{{
                //    return response.Fail(""名称已存在"");
                //}}

                entity = _{1}Service.Find(request.Id);
                if (entity == null)
                {{
                    return response.Fail(""数据异常"");
                }}


                entity.Remark = request.Remark;
                entity.UpdateUser = CurrentUser.Account.Id;
                entity.UpdateTime = now;

               {2}

                bool flag = _{1}Service.Update(entity);

                return flag ? response.Sucess(""修改成功"") : response.Fail(""修改失败"");
            }}


        }}

        /// <summary>
        /// {0}-删除
        /// </summary>
        /// <param name=""request""></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResultL Delete{0}(DeleteRequest request)
        {{
            JsonResultL response = new JsonResultL();
            DateTime now = DateTime.Now;
            string tempUser = HttpContext.Request.Headers[""LUserInfo""].ToString();
            AccountLoginInfo CurrentUser = JsonConvert.DeserializeObject<AccountLoginInfo>(tempUser);

            if (CurrentUser == null || CurrentUser.Account == null)
            {{
                return response.TokenFail(""用户异常"");
            }}
            if (string.IsNullOrWhiteSpace(request.Id))
            {{
                return response.Fail(""参数错误"");
            }}
          

            var entity = _{1}Service.Find(request.Id);
            if (entity == null)
            {{
                return response.Fail(""数据异常"");
            }}

            //软删除
            entity.IsDelete = true;
            entity.DeleteUser = CurrentUser.Account.Id;
            entity.DeleteTime = now;

            bool flag = _{1}Service.Update(entity);


            return flag ? response.Sucess(""删除成功"") : response.Fail(""删除失败"");
        }}
    }}
}}
", tableName, tableName2, str);



            return res;
        }
        /// <summary>
        /// vue 接口代码生成
        /// </summary>
        /// <param name="colList"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private string GetCode2(List<CodeCreateTableColInfo> colList, string tableName)
        {
            string res = string.Format(@"
import {{ requestPost, requestGet }} from '@/service/requestL'
// 获取{0}列表
export function Get{0}List(data) {{
     return requestPost({{
         url: ""/api/{0}/Get{0}List"",
         data: data
     }})
}}
 // 删除{0}
export function Delete{0}(id) {{
           return requestPost({{
              url: ""/api/{0}/Delete{0}"",
                data: {{ id: id }}
           }})
}}
// 保存{0}
export function Save{0}(data) {{
         return requestPost({{
             url: ""/api/{0}/Save{0}"",
             data: data
         }})
}}", tableName);


            return res;
        }
        /// <summary>
        /// vue 代码代码生成
        /// </summary>
        /// <param name="colList"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private string GetCode1(List<CodeCreateTableColInfo> colList, string tableName)
        {
  
            string str0 = "";
            string str1 = "";
            string str2 = tableName;
            string str3 = "";
            string str4 = "";
            string str5 = "";

            foreach (var item in colList)
            {
                #region str0 
                string tempstr0 = string.Format(@"<el-table-column label=""{0}"" align=""center"">
                                                   <template slot-scope=""scope"">
                                                       {{{{ scope.row.{1} }}}}
                                                   </template>
                                               </el-table-column>", item.Remark,item.Name);

                str0 = str0 + tempstr0;
                #endregion

                #region str1
                string tempstr1 = string.Format(@"<el-form-item label=""{0}"">
                                                     <el-input v-model=""form.{1}"" class=""l-input-form"" placeholder=""{0}""></el-input>
                                                 </el-form-item>", item.Remark, item.Name);

                if (item.TypeName.IndexOf("DateTime")>-1)
                {
                    tempstr1 = string.Format(@"<el-form-item label=""{0}"">
                                                    <el-date-picker type=""date"" placeholder=""选择日期"" v-model=""form.{1}""></el-date-picker>
                                                 </el-form-item>", item.Remark, item.Name);
                }
                

                str1 = str1 + tempstr1;
                #endregion

                #region str3 
                string tempstr3 = string.Format(@"{0}: """",", item.Name);

                if (item.TypeName== "int" || item.TypeName== "decimal")
                {
                  
                }

                str3 = str3 + tempstr3;
                #endregion

                #region str4
                string tempstr4 = string.Format(@"this.form.{0} = """";", item.Name);

                if (item.TypeName == "int" || item.TypeName == "decimal")
                {
                    tempstr4 = string.Format(@"this.form.{0} = 0;", item.Name);
                }

                str4 = str4 + tempstr4;
                #endregion

                #region str5
                string tempstr5 = string.Format(@"this.form.{0} = row.{0};", item.Name);

                str5 = str5 + tempstr5;
                #endregion
            }
        

            string res = string.Format(@"<template>
                <div id=""app"">
                    <div  class=""box"">
                        <div>
                            <template v-if=""$PowerSelect(userPower, currentPagePower)"">
                                <el-input class=""l-input"" v-model=""search.keyWords"" placeholder=""关键字搜索""></el-input>
                                <el-button type=""primary"" class=""l-margin-l15"" v-on:click=""getList"">查询</el-button>
                            </template>


                            <el-button v-if=""$PowerAdd(userPower, currentPagePower)"" type=""success"" v-on:click=""onAdd"">新增</el-button>
                        </div>
                    </div>
                    <div class=""box"">
                        <el-table :data=""list"" border  :height=""`calc(100vh - 305px)`"" :highlight-current-row=""true"">

                            {0}
                            <el-table-column label=""描述"" align=""center"">
                                <template slot-scope=""scope"">
                                    {{{{ scope.row.remark }}}}
                                </template>
                            </el-table-column>

                            <el-table-column label=""操作"" width=""200"" fixed=""right"" align=""center"">
                                <template slot-scope=""scope"">
                                    <el-button type=""primary"" size=""mini""
                                        v-if=""$PowerUpdate(userPower, currentPagePower)"" plain
                                        v-on:click=""onEdit(scope.row)"">编辑</el-button>
                                    <el-button type=""danger"" size=""mini"" v-if=""$PowerDelete(userPower,currentPagePower)""
                                        plain v-on:click=""onDelete(scope.row)"">删除</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </div>
                    <div style=""height: 10px"">&nbsp;</div>
                    <div class=""box"">
                        <el-pagination v-on:size-change=""handleSizeChange"" v-on:current-change=""handleCurrentChange""
                            v-bind:current-page=""currentPage"" v-bind:page-sizes=""[10, 20, 30, 40]"" v-bind:page-size=""pagesize""
                            layout=""total, sizes, prev, pager, next, jumper"" v-if=""reflushPageFlag"" v-bind:total=""total"">
                        </el-pagination>
                    </div>
                    <!--对话框-->
                    <el-dialog :title=""EditTitle"" :close-on-click-modal=""false"" :visible.sync=""dialogVisible"" width=""30%""  custom-class=""l-dialog"">
                        <div class=""l-div-400"">

                            <el-form ref=""form"" :model=""form"" label-width=""130px"">
                                <el-row>
                                    <el-col :span=""24"">
                                       {1}
                                        <el-form-item label=""描述"">
                                            <el-input v-model=""form.remark"" class=""l-input-form"" placeholder=""描述"">
                                            </el-input>
                                        </el-form-item>

                                    </el-col>

                                </el-row>


                            </el-form>

                        </div>
                        <span slot=""footer"" class=""dialog-footer"">
                            <el-button v-on:click=""dialogVisible = false"">取 消</el-button>
                            <el-button type=""primary"" v-on:click=""onSave"">确 定</el-button>
                        </span>
                    </el-dialog>
                </div>
            </template>

            <script>

            import {{ Get{2}List,Delete{2},Save{2} }} from '@/service/{2}api';//地址改为实际地址
            export default {{
                data() {{
                    return {{
                        userPower: '',
                        currentPagePower: '',
                        search: {{
                            keyWords: """"
                        }},
                        //分页 开始
                        currentPage: 1,
                        pagesize: 10,
                        total: 0,
                        reflushPageFlag: true,
                        //分页 结束
                        isAdd: true,
                        list: [],
                        dialogVisible: false,
                        EditTitle: """",
                        form: {{
                            id: """",
                            remark: """",
                            {3}
                        }},
                    }};
                }},
                created() {{

                    this.currentPagePower=this.$route.query.powercode;
                    this.userPower = localStorage.getItem(""userPower"");
                    this.InitData();
                }},
                watch: {{}},
                methods: {{

                    //初始化
                    InitData() {{

                        if (this.$PowerSelect(this.userPower, this.currentPagePower)) {{
                            this.getList();
                        }}

                    }},
                    //查询列表
                    getList() {{
                        this.openLoading();
                        this.list = [];
                        var that = this;

                        let jsondata = {{
                            PageIndex: this.currentPage,
                            PageSize: this.pagesize,
                            keyWords: this.search.keyWords
                        }};
                        Get{2}List(jsondata).then(res => {{

                            if (res.data != undefined) {{
                                that.list = res.data.list;
                                that.total = res.data.total;

                                that.$nextTick(function () {{
                                    that.reflushPageFlag = true;
                                }});
                            }}
                             that.closeLoading();
                        }}).catch(err => {{
                            this.$message.error(""数据请求异常"");
                            that.closeLoading();
                        }})

                    }},

                    //初始化表单
                    initForm() {{
                        this.form.id = """";
                        this.form.remark = """";
                        {4}

                    }},
                    onAdd() {{
                        this.initForm();

               //有排序字段可以放开
                        // if (this.list != null && this.list.length > 0) {{
                        //     let currentList = this.list.sort(function (a, b) {{ return b.sort - a.sort; }})[0];
                        //     this.form.sort = currentList.sort + 1;

                        //     //重新排序一下 这是个小bug
                        //     this.list.sort(function (a, b) {{ return a.sort - b.sort; }});
                        // }}

                        this.isAdd = true;
                        this.dialogVisible = true;
                        this.EditTitle = ""新增"";
                    }},
                    onEdit(row) {{
                        this.initForm();
                        this.isAdd = false;
                        this.dialogVisible = true;
                        this.EditTitle = ""修改"";

                        //赋值
                        this.form.id = row.id;
                        this.form.remark = row.remark;
                        {5}
                    }},
                    onDelete(row) {{
                        var that = this;
                        this.$confirm(""是否删除?"", ""提示"", {{
                            confirmButtonText: ""确定"",
                            cancelButtonText: ""取消"",
                            type: ""warning"",
                        }}).then(() => {{
                            that.openLoading();
                            Delete{2}(row.id).then(res => {{
                                that.closeLoading();
                                console.log(res);
                                if (res.success) {{
                                    that.getList();
                                    that.$message({{ message: ""删除成功"", type: ""success"" }});
                                }} else {{
                                    that.$message.error(res.msg);
                                }}
                            }}).catch(err => {{
                                that.$message.error(""删除失败"");
                                that.closeLoading();
                            }})

                        }});
                    }},
                    onSave() {{
                        var that = this;
                        that.openLoading();

                        Save{2}(this.form).then(res => {{
                            console.log(res);
                            that.closeLoading();
                            if (res.success) {{
                                that.$message({{ message: ""操作成功"", type: ""success"" }});
                                that.getList();
                                that.dialogVisible = false;
                            }} else {{
                                that.$message.error(res.msg);
                            }}
                        }}).catch(err => {{
                            that.$message.error(""操作失败"");
                            that.closeLoading();
                        }})

                    }},
                    //当前条
                    handleSizeChange(val) {{
                        this.pagesize = val;
                        this.getList();
                    }},
                    //当前页
                    handleCurrentChange(val) {{
                        this.currentPage = val;
                        this.getList();
                    }},

                }},
            }};
            </script>

            <style scoped>


            .l-input {{
                display: inline-block;
                width: 260px;
            }}

            .l-input-form {{
                display: inline-block;
                width: 220px;
            }}

            .l-margin-l15 {{
                margin-left: 15px;
            }}

            .l-red {{
                color: red;
            }}
            </style>", str0, str1, str2, str3, str4, str5);



            return res;
        }

        private string Gettab(int num=1)
        {
            string res = "";

            for (int i = 0; i < num; i++)
            {
                res += "\t";
            }

            return res;
        }

        private string Getbr()
        {
            return "\n";
        }

        /// <summary>
        /// 返回类型
        /// </summary>
        /// <returns></returns>
        private static string TypeStr(string typestr)
        {
            if (typestr == "Decimal")
            {
                return "decimal";
            }
            else if (typestr == "String")
            {
                return "string";
            }
            else if (typestr == "Boolean")
            {
                return "bool";
            }
            else if (typestr == "Int32")
            {
                return "int";
            }
            else if (typestr == "DateTime")
            {
                return "DateTime";
            }
            else if (typestr == "nullable`1")
            {
                return "DateTime?";
            }
            else
            {
                return "DateTime?";
            }
        }

    }
}
